home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / binutils.7 / binutils / binutils-2.7 / ld / emultempl / hppaelf.em < prev    next >
Encoding:
Text File  |  1996-07-04  |  7.4 KB  |  287 lines

  1. # This shell script emits a C file. -*- C -*-
  2. # It does some substitutions.
  3. cat >e${EMULATION_NAME}.c <<EOF
  4. /* An emulation for HP PA-RISC ELF linkers.
  5.    Copyright (C) 1991, 1993 Free Software Foundation, Inc.
  6.    Written by Steve Chamberlain steve@cygnus.com
  7.  
  8. This file is part of GLD, the Gnu Linker.
  9.  
  10. This program is free software; you can redistribute it and/or modify
  11. it under the terms of the GNU General Public License as published by
  12. the Free Software Foundation; either version 2 of the License, or
  13. (at your option) any later version.
  14.  
  15. This program is distributed in the hope that it will be useful,
  16. but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18. GNU General Public License for more details.
  19.  
  20. You should have received a copy of the GNU General Public License
  21. along with this program; if not, write to the Free Software
  22. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  23.  
  24. #include "bfd.h"
  25. #include "sysdep.h"
  26. #include "bfdlink.h"
  27.  
  28. #include "ld.h"
  29. #include "ldemul.h"
  30. #include "ldfile.h"
  31. #include "ldexp.h"
  32. #include "ldlang.h"
  33. #include "ldmisc.h"
  34. #include "ldmain.h"
  35. #include "ldctor.h"
  36.  
  37. /* Section in which we build stubs.  */
  38. static asection *stub_sec;
  39. static lang_input_statement_type *stub_file;
  40.  
  41.  
  42. /* FIXME.  This doesn't belong here.  */
  43. extern lang_statement_list_type file_chain;
  44.  
  45. /* Perform some emulation specific initialization.  For PA ELF we set
  46.    up the local label prefix and the output architecture.  */
  47.  
  48. static void
  49. hppaelf_before_parse ()
  50. {
  51.   link_info.lprefix = "L$";
  52.   link_info.lprefix_len = 2;
  53.  
  54.   ldfile_output_architecture = bfd_arch_hppa;
  55. }
  56.  
  57. /* Set the output architecture and machine.  */
  58.  
  59. static void
  60. hppaelf_set_output_arch()
  61. {
  62.   unsigned long machine = 0;
  63.  
  64.   bfd_set_arch_mach (output_bfd, ldfile_output_architecture, machine);
  65. }
  66.  
  67. /* This is called before the input files are opened.  We create a new
  68.    fake input file to hold the stub section.  */
  69.  
  70. static void
  71. hppaelf_create_output_section_statements ()
  72. {
  73.   stub_file = lang_add_input_file ("linker stubs",
  74.                    lang_input_file_is_fake_enum,
  75.                    NULL);
  76.   stub_file->the_bfd = bfd_create ("linker stubs", output_bfd);
  77.   if (stub_file->the_bfd == NULL
  78.       || ! bfd_set_arch_mach (stub_file->the_bfd,
  79.                   bfd_get_arch (output_bfd),
  80.                   bfd_get_mach (output_bfd)))
  81.     {
  82.       einfo ("%X%P: can not create BFD %E\n");
  83.       return;
  84.     }
  85.  
  86.   stub_sec = bfd_make_section_old_way (stub_file->the_bfd, ".text");
  87.   /* Don't set SEC_RELOC until we actually have relocations in this
  88.      section.  */
  89.   if (stub_sec == NULL
  90.       || ! bfd_set_section_flags (stub_file->the_bfd, stub_sec,
  91.                   (SEC_HAS_CONTENTS
  92.                    | SEC_ALLOC
  93.                    | SEC_LOAD
  94.                    | SEC_CODE
  95.                    | SEC_IN_MEMORY)))
  96.     {
  97.       einfo ("%X%P: can not create stub section: %E\n");
  98.       return;
  99.     }
  100.  
  101.   ldlang_add_file (stub_file);
  102. }
  103.  
  104. /* Walk all the lang statements splicing out any padding statements from 
  105.    the list.  */
  106.  
  107. static void
  108. hppaelf_delete_padding_statements (s, prev)
  109.      lang_statement_union_type *s;
  110.      lang_statement_union_type **prev;
  111. {
  112.   lang_statement_union_type *sprev = NULL;
  113.   for (; s != NULL; s = s->next)
  114.     {
  115.       switch (s->header.type)
  116.     {
  117.  
  118.     /* We want recursively walk these sections.  */
  119.     case lang_constructors_statement_enum:
  120.       hppaelf_delete_padding_statements (constructor_list.head,
  121.                          &constructor_list.head);
  122.       break;
  123.  
  124.     case lang_output_section_statement_enum:
  125.       hppaelf_delete_padding_statements (s->output_section_statement.
  126.                            children.head,
  127.                          &s->output_section_statement.
  128.                            children.head);
  129.       break;
  130.  
  131.     /* Huh?  What is a lang_wild_statement?  */
  132.     case lang_wild_statement_enum:
  133.       hppaelf_delete_padding_statements (s->wild_statement.
  134.                            children.head,
  135.                          &s->wild_statement.
  136.                            children.head);
  137.       break;
  138.  
  139.     /* Here's what we are really looking for.  Splice these out of
  140.        the list.  */
  141.     case lang_padding_statement_enum:
  142.       if (sprev)
  143.         sprev->header.next = s->header.next;
  144.       else
  145.         **prev = *s;
  146.       break;
  147.  
  148.     /* We don't care about these cases.  */
  149.     case lang_data_statement_enum:
  150.     case lang_object_symbols_statement_enum:
  151.     case lang_output_statement_enum:
  152.     case lang_target_statement_enum:
  153.     case lang_input_section_enum:
  154.     case lang_input_statement_enum:
  155.     case lang_assignment_statement_enum:
  156.     case lang_address_statement_enum:
  157.       break;
  158.  
  159.     default:
  160.       abort ();
  161.       break;
  162.     }
  163.       sprev = s;
  164.     }
  165. }
  166.  
  167. /* Final emulation specific call.  For the PA we use this opportunity
  168.    to build linker stubs.  */
  169.  
  170. static void
  171. hppaelf_finish ()
  172. {
  173.   /* Call into the BFD backend to do the real work.  */
  174.   if (elf32_hppa_size_stubs (stub_file->the_bfd, output_bfd, &link_info)
  175.       == false)
  176.     {
  177.       einfo ("%X%P: can not size stub section: %E\n");
  178.       return;
  179.     }
  180.   
  181.   /* If the size of the stub section is nonzero, then we need
  182.      to resize the sections, recompute the assignments, and finally
  183.      build the stubs.  */
  184.   if (bfd_section_size (stub_file->the_bfd, stub_file->the_bfd->sections) != 0)
  185.     {
  186.       /* Delete all the padding statements, they're no longer valid.  */
  187.       hppaelf_delete_padding_statements (stat_ptr->head, &stat_ptr->head);
  188.       
  189.       /* Resize the sections.  */
  190.       lang_size_sections (stat_ptr->head, abs_output_section,
  191.               &stat_ptr->head, 0, (bfd_vma) 0, false);
  192.       
  193.       /* Redo special stuff.  */
  194.       ldemul_after_allocation ();
  195.       
  196.       /* Do the assignments again.  */
  197.       lang_do_assignments (stat_ptr->head,
  198.                abs_output_section,
  199.                (fill_type) 0, (bfd_vma) 0);
  200.       
  201.       /* Now build the linker stubs.  */
  202.       if (elf32_hppa_build_stubs (stub_file->the_bfd, &link_info) == false)
  203.     {
  204.       einfo ("%X%P: can not build stubs: %E\n");
  205.       return;
  206.     }
  207.     }
  208. }
  209.  
  210. /* The script itself gets inserted here.  */
  211.  
  212. static char *
  213. hppaelf_get_script(isfile)
  214.      int *isfile;
  215. EOF
  216.  
  217. if test -n "$COMPILE_IN"
  218. then
  219. # Scripts compiled in.
  220.  
  221. # sed commands to quote an ld script as a C string.
  222. sc='s/["\\]/\\&/g
  223. s/$/\\n\\/
  224. 1s/^/"/
  225. $s/$/n"/
  226. '
  227.  
  228. cat >>e${EMULATION_NAME}.c <<EOF
  229. {                 
  230.   *isfile = 0;
  231.  
  232.   if (link_info.relocateable == true && config.build_constructors == true)
  233.     return `sed "$sc" ldscripts/${EMULATION_NAME}.xu`;
  234.   else if (link_info.relocateable == true)
  235.     return `sed "$sc" ldscripts/${EMULATION_NAME}.xr`;
  236.   else if (!config.text_read_only)
  237.     return `sed "$sc" ldscripts/${EMULATION_NAME}.xbn`;
  238.   else if (!config.magic_demand_paged)
  239.     return `sed "$sc" ldscripts/${EMULATION_NAME}.xn`;
  240.   else
  241.     return `sed "$sc" ldscripts/${EMULATION_NAME}.x`;
  242. }
  243. EOF
  244.  
  245. else
  246. # Scripts read from the filesystem.
  247.  
  248. cat >>e${EMULATION_NAME}.c <<EOF
  249. {                 
  250.   *isfile = 1;
  251.  
  252.   if (link_info.relocateable == true && config.build_constructors == true)
  253.     return "ldscripts/${EMULATION_NAME}.xu";
  254.   else if (link_info.relocateable == true)
  255.     return "ldscripts/${EMULATION_NAME}.xr";
  256.   else if (!config.text_read_only)
  257.     return "ldscripts/${EMULATION_NAME}.xbn";
  258.   else if (!config.magic_demand_paged)
  259.     return "ldscripts/${EMULATION_NAME}.xn";
  260.   else
  261.     return "ldscripts/${EMULATION_NAME}.x";
  262. }
  263. EOF
  264.  
  265. fi
  266.  
  267. cat >>e${EMULATION_NAME}.c <<EOF
  268.  
  269. struct ld_emulation_xfer_struct ld_hppaelf_emulation = 
  270. {
  271.   hppaelf_before_parse,
  272.   syslib_default,
  273.   hll_default,
  274.   after_parse_default,
  275.   after_open_default,
  276.   after_allocation_default,
  277.   hppaelf_set_output_arch,
  278.   ldemul_default_target,
  279.   before_allocation_default,
  280.   hppaelf_get_script,
  281.   "hppaelf",
  282.   "elf32-hppa",
  283.   hppaelf_finish,
  284.   hppaelf_create_output_section_statements,
  285. };
  286. EOF
  287.